from time import sleep
from tkinter import *
from tkinter import ttk
from tkinter import filedialog
from tkinter import messagebox
import time

import win32clipboard
import configparser
import func_timeout

from util.time import *
from util.trans import *
from util.divide_text_by_lines import *
from util.hanzi import *
from util.my_kafka import *


class EditAddMocoDialog(Toplevel):
    '''
    接口新增/编辑界面
    '''

    def __init__(self, Interface):
        super().__init__()
        self.name = Interface['name']
        self.method = Interface['method']
        self.url = Interface['url']
        self.content = Interface['content']
        self.title('编辑/新建模拟接口')
        # 弹窗界面
        self.setup_UI()

    def setup_UI(self):
        # 第一行（两列）
        width_all = 100
        row1 = Frame(self)
        row1.pack(fill="x")
        Label(row1, text='接口名称：', width=8).pack(side=LEFT)
        # self.name = StringVar()
        self.name_Entry = Entry(row1, width=width_all)
        self.name_Entry.insert(0, self.name)
        self.name_Entry.pack(side=LEFT)
        # 第二行
        row2 = Frame(self)
        row2.pack(fill="x", ipadx=1, ipady=1)
        Label(row2, text='接口类型', width=8).pack(side=LEFT)
        self.method_radio = IntVar()
        self.method_radio.set(0 if self.method == "post" else 1)
        Radiobutton(row2, text="post", variable=self.method_radio, value=0).pack(side=LEFT)
        Radiobutton(row2, text="get", variable=self.method_radio, value=1).pack(side=LEFT)
        # self.method_Entry = Entry(row2, width=width_all)
        # self.method_Entry.insert(0,self.method)
        # self.method_Entry.pack(side=LEFT)
        # 第三行
        row3 = Frame(self)
        row3.pack(fill="x", ipadx=1, ipady=1)
        Label(row3, text='url', width=8).pack(side=LEFT)
        # self.age = IntVar()
        self.url_Entry = Entry(row3, width=width_all)
        self.url_Entry.insert(0, self.url)
        self.url_Entry.pack(side=LEFT)
        # 第四行
        row4 = Frame(self)
        row4.pack(fill="x", ipadx=1, ipady=1)
        Label(row4, text='返回内容', width=8).pack(side=LEFT)
        # self.age = IntVar()
        self.content_Text = Text(row4, width=width_all)
        self.content_Text.insert(1.0, self.content)
        self.content_Text.pack(side=LEFT)
        # 第五行
        row5 = Frame(self)
        row5.pack(fill="x")
        Button(row5, text="取消", command=self.cancel).pack(side=RIGHT)
        Button(row5, text="确定", command=self.ok).pack(side=RIGHT)

    def ok(self):
        self.name = self.name_Entry.get()
        self.method = "post" if self.method.get() == 0 else "get"
        self.url = self.url_Entry.get()
        self.content = self.content_Text.get(1.0, END)
        self.userinfo = [self.name, self.method, self.url, self.content]  # 设置数据
        self.destroy()  # 销毁窗口

    def cancel(self):
        self.userinfo = [self.name, self.method, self.url, self.content]  # 返回原值！
        self.destroy()


class settings(Toplevel):
    '''
    设置页面
    '''

    def __init__(self, page_show_dic):
        super().__init__()
        self.title('页面设置')
        self.settingsFrame = Frame(self)
        self.settingsFrame.grid(row=1, column=1)
        Label(self.settingsFrame, text="选择展示的页签").pack(side=TOP)
        self.pageSetting = Frame(self)
        self.pageSetting.grid(row=1, column=2)
        self.checkVarDic = {}
        self.checkbuttonDic = {}
        self.page_display_dic = {}
        self.pageList = list(page_show_dic.keys())
        for pageName in self.pageList:
            CheckVar = IntVar()
            CheckVar.set(page_show_dic[pageName])
            checkbutton = Checkbutton(self.pageSetting, text=pageName, variable=CheckVar, onvalue=1, offvalue=0)
            checkbutton.grid(sticky=W)
            sleep(0.1)
            self.checkbuttonDic[pageName] = checkbutton
            self.checkVarDic[pageName] = CheckVar
        self.buttonFrame = Frame(self)
        self.buttonFrame.grid(row=2, column=1, columnspan=2)
        Button(self.buttonFrame, text="确定", command=self.pageSettings).pack()
        # CheckVar1 = IntVar()
        # CheckVar2 = IntVar()
        # Checkbutton(self.pageSetting, text = "RUNOOB", variable = CheckVar1, onvalue = 1, offvalue = 0).pack()

    def pageSettings(self):
        self.page_display_dic = {}
        for pageName in self.pageList:
            self.page_display_dic[pageName] = self.checkVarDic[pageName].get()
        self.destroy()


class dataTransPage(ttk.Frame):
    def __init__(self, nb):
        super().__init__(nb)
        self.LOG_LINE_NUM = 0
        # 第一个选项卡
        # 标签
        self.init_data_label = Label(self, text="待处理数据")
        self.init_data_label.grid(row=0, column=0)
        self.result_data_label = Label(self, text="输出结果")
        self.result_data_label.grid(row=0, column=12)
        self.log_label = Label(self, text="日志")
        self.log_label.grid(row=12, column=0)
        # 文本框
        self.input_data_Text = Text(self, width=67, height=35)  # 原始数据录入框
        self.input_data_Text.grid(row=1, column=0, rowspan=10, columnspan=10)
        self.result_data_Text = Text(self, width=70, height=49)  # 处理结果展示
        self.result_data_Text.grid(row=1, column=12, rowspan=15, columnspan=10)
        self.log_data_Text = Text(self, width=66, height=9, state=DISABLED)  # 日志框
        self.log_data_Text.grid(row=13, column=0, columnspan=10)
        # 按钮
        Button(self, text="hbase转换", bg="lightblue", width=10, command=self.str_trans_hbase).grid(row=1, column=11)
        # Button(self, text="url编码转换", bg="lightblue", width=10,command=self.str_trans_url).grid(row=2, column=11)
        Button(self, text="时间转换", bg="lightblue", width=10, command=self.str_trans_time).grid(row=3, column=11)
        Button(self, text="获取当前时间", bg="lightblue", width=10, command=self.str_get_time).grid(row=4, column=11)
        Button(self, text="简体转繁体", bg="lightblue", width=10, command=self.hans2hant).grid(row=5, column=11)
        Button(self, text="繁体转简体", bg="lightblue", width=10, command=self.hant2hans).grid(row=6, column=11)
        Button(self, text="清空数据", bg="lightblue", width=10, command=self.clear_data).grid(row=7, column=11)
        Button(self, text="复制结果", bg="lightblue", width=10, command=self.copyresultdata).grid(row=8, column=11)
        Button(self, text="清空日志", bg="lightblue", width=10, command=self.clear_datalog).grid(row=12, column=1)

    # 获取当前时间
    def get_current_time(self):
        current_time = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))
        return current_time

    # 日志动态打印
    def write_log_to_Text(self, logmsg):
        self.log_data_Text.config(state=NORMAL)
        current_time = self.get_current_time()
        logmsg_in = str(current_time) + " " + str(logmsg) + "\n"  # 换行
        if self.LOG_LINE_NUM <= 7:
            self.log_data_Text.insert(END, logmsg_in)
            self.LOG_LINE_NUM = self.LOG_LINE_NUM + 1
        else:
            self.log_data_Text.delete(1.0, 2.0)
            self.log_data_Text.insert(END, logmsg_in)
        self.log_data_Text.config(state=DISABLED)

    def str_trans_hbase(self):
        src = self.input_data_Text.get(1.0, END).strip().replace("\n", "")
        if src:
            try:
                resultData = strans(src)
                self.result_data_Text.delete(1.0, END)
                self.result_data_Text.insert(1.0, resultData)
                # write_log_to_Text("INFO: success")
            except:
                self.result_data_Text.delete(1.0, END)
                self.result_data_Text.insert(1.0, "字符串转失败")
        else:
            self.write_log_to_Text("ERROR: failed")

    def str_trans_url(self):
        src = self.input_data_Text.get(1.0, END).strip().replace("\n", "").encode()
        if src:
            try:
                resultData = parse.unquote(strans(src))
                self.result_data_Text.delete(1.0, END)
                self.result_data_Text.insert(1.0, resultData)
            except:
                self.result_data_Text.delete(1.0, END)
                self.result_data_Text.insert(1.0, "字符串转失败")
        else:
            self.write_log_to_Text("ERROR: failed")

    def str_trans_time(self):
        src = self.input_data_Text.get(1.0, END).strip()
        if src:
            try:
                resultData = time_trans(src)
                self.result_data_Text.delete(1.0, END)
                self.result_data_Text.insert(1.0, resultData)
                src_times = src.split("\n")
                out_times = resultData.split("\n")
                for i, src_time in enumerate(src_times):
                    self.write_log_to_Text("INFO: " + src_time + " To: " + out_times[i])
            except:
                self.result_data_Text.delete(1.0, END)
                self.result_data_Text.insert(1.0, "字符串转失败")
        else:
            self.write_log_to_Text("ERROR: failed")

    def str_get_time(self):
        time_now = time.time()
        stamp_now = str(int(round(time_now * 1000)))
        resultData = "时间戳为：     " + stamp_now + "\n时间格式显示： " + stamp_to_date(stamp_now)
        self.result_data_Text.delete(1.0, END)
        self.result_data_Text.insert(1.0, resultData)

    def hans2hant(self):
        src = self.input_data_Text.get(1.0, END).strip()
        if src:
            try:
                self.result_data_Text.delete(1.0, END)
                self.result_data_Text.insert(1.0, hans_2_hant(src))
            except:
                self.result_data_Text.delete(1.0, END)
                self.result_data_Text.insert(1.0, "字符串转失败")
        else:
            self.write_log_to_Text("ERROR: failed")

    def hant2hans(self):
        src = self.input_data_Text.get(1.0, END).strip()
        if src:
            try:
                self.result_data_Text.delete(1.0, END)
                self.result_data_Text.insert(1.0, hant_2_hans(src))
            except:
                self.result_data_Text.delete(1.0, END)
                self.result_data_Text.insert(1.0, "字符串转失败")
        else:
            self.write_log_to_Text("ERROR: failed")

    def clear_data(self):
        self.result_data_Text.delete(1.0, END)
        self.input_data_Text.delete(1.0, END)

    def clear_datalog(self):
        self.LOG_LINE_NUM = 0
        self.log_data_Text.config(state=NORMAL)
        self.log_data_Text.delete(1.0, END)
        self.log_data_Text.config(state=DISABLED)
        # LOG_LINE_NUM = 0

    def copyresultdata(self):
        copystring = self.result_data_Text.get(1.0, END)[:-1]
        win32clipboard.OpenClipboard()
        win32clipboard.EmptyClipboard()
        win32clipboard.SetClipboardText(copystring, win32clipboard.CF_TEXT)
        win32clipboard.CloseClipboard()
        self.write_log_to_Text("INFO: 复制结果到剪贴板")


class fileTransPage(ttk.Frame):
    def __init__(self, nb):
        super().__init__(nb)
        # 第二个选项卡
        text_width = 130
        Label(self, text="输入文件").grid(row=0, column=0, sticky=W)
        Label(self, text="输出路径").grid(row=1, column=0, sticky=W)
        Label(self, text="转换模式").grid(row=3, column=0, sticky=W)
        Label(self, text="日志").grid(row=8, column=0, sticky=W + N)
        # button_opt = {'fill': constants.BOTH}
        # font_text = tf.Font(family='宋体',size=14)
        self.file_path_Text = Text(self, width=text_width, height=1)
        self.file_path_Text.grid(row=0, column=1)
        Button(self, text="文件选择", command=self.selectfile).grid(row=0, column=2, sticky=W)
        self.path_Text = Text(self, width=text_width, height=1)
        self.path_Text.grid(row=1, column=1)
        Button(self, text="路径选择", command=self.selectpath).grid(row=1, column=2, sticky=W)
        # 单选规则
        self.v = IntVar()
        self.v.set(0)
        Radiobutton(self, text="hbase转换", variable=self.v, value=0).grid(row=3, column=1, sticky=W)
        # Radiobutton(self,text ="url编码转换",variable = self.v,value =1).grid(row=4,column=1,  sticky=W)
        Radiobutton(self, text="简体转繁体", variable=self.v, value=2).grid(row=5, column=1, sticky=W)
        Radiobutton(self, text="繁体转简体", variable=self.v, value=3).grid(row=6, column=1, sticky=W)
        # 转换按键
        Button(self, text="开始转换", command=self.tran_file).grid(row=3, column=2, sticky=W)
        # 输出log框
        self.page2logText = Text(self, width=text_width + 10, height=30, state=NORMAL)
        self.page2logText.grid(row=8, column=1, columnspan=2)

    def selectfile(self):

        # get filename
        filename = filedialog.askopenfilename(initialdir="C:\\", title="This is title", parent=self)
        self.file_path_Text.delete(1.0, END)
        self.file_path_Text.insert(1.0, filename)

    def selectpath(self):
        # get filename
        filename = filedialog.askdirectory(initialdir="C:\\", title="This is title", parent=self)
        self.path_Text.delete(1.0, END)
        self.path_Text.insert(1.0, filename)

    trans_model_dic = {"hbase转换": 0, "url编码转换": 1, "简体转繁体": 2, "繁体转简体": 3}
    trans_model_list = list(trans_model_dic.keys())

    switch = {
        'hbase转换': strans,
        '简体转繁体': hans_2_hant,
        '繁体转简体': hant_2_hans,
        'url编码转换': strans_url
    }

    def get_current_time(self):
        current_time = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))
        return current_time

    def tran_file(self):
        global trans_model_dic
        input_file_name = self.file_path_Text.get(1.0, END)[:-1]
        output_path_name = self.path_Text.get(1.0, END)[:-1]
        if output_path_name == '' or (not os.path.exists(output_path_name)):
            output_path_name = "D:/"
            msg = self.get_current_time() + "\t输出路径为空或者不存在，使用默认输出路径：  D:/\n"
            self.page2logText.insert(END, msg)
        input_file_name_ex = os.path.splitext(os.path.basename(input_file_name))
        output_file_name = os.path.join(output_path_name, input_file_name_ex[0] + "stran" + input_file_name_ex[1])
        mode = self.trans_model_list[self.v.get()]
        msg = self.get_current_time() + "\t开始将文件" + input_file_name + "进行" + mode + "，输出至文件" + output_file_name + "\n"
        self.page2logText.insert(END, msg)
        if os.path.exists(input_file_name) and os.path.isfile(input_file_name):
            outputFile = open(output_file_name, "w", encoding="utf-8")
            with open(input_file_name, encoding="utf-8") as inputFile:
                i = 0
                line = inputFile.readline()
                while line:
                    output_string = self.switch.get(mode, strans)(line)
                    outputFile.writelines(output_string)
                    line = inputFile.readline()
                    i = i + 1
                    if i % 1000 == 0:
                        msg = self.get_current_time() + "\t已经处理" + str(i) + "行数据\n"
                        self.page2logText.insert(END, msg)
            outputFile.close()
            msg = self.get_current_time() + "\t转换完成！请查看输出文件：" + output_file_name + "\n"
            self.page2logText.insert(END, msg)

        else:
            error_string = self.get_current_time() + "\t输入的文件不存在！\n"
            self.page2logText.insert(END, error_string)


class fileDividePage(ttk.Frame):
    def __init__(self, nb):
        super().__init__(nb)
        # 第三个选项卡
        text_width = 130
        Label(self, text="大文件选择:").grid(row=0, column=0, sticky=E)
        Label(self, text="输出路径选择:").grid(row=1, column=0, sticky=E)
        Label(self, text="输出小文件行数:").grid(row=2, column=0, sticky=E)
        Label(self, text="输出小文件个数:").grid(row=2, column=2, sticky=E)
        self.file_path_Text = Text(self, width=text_width, height=1)
        self.file_path_Text.grid(row=0, column=1, columnspan=4)
        Button(self, text="文件选择", command=self.selectfile).grid(row=0, column=5, sticky=W)
        self.path_Text = Text(self, width=text_width, height=1)
        self.path_Text.grid(row=1, column=1, columnspan=4)
        self.get_small_file_lins_Text = Text(self, width=20, height=1)
        self.get_small_file_lins_Text.grid(row=2, column=1, sticky=W)
        self.get_small_file_lins_Text.insert(1.0, '1000')
        self.get_small_file_number_Text = Text(self, width=20, height=1)
        self.get_small_file_number_Text.grid(row=2, column=3, sticky=W)
        self.get_small_file_number_Text.insert(1.0, '30')
        Button(self, text="路径选择", command=self.selectpath).grid(row=1, column=5, sticky=W)
        Button(self, text="开始转换", command=self.divide).grid(row=2, column=5, sticky=W)

    def selectfile(self):
        filename = filedialog.askopenfilename(initialdir="C:\\", title="This is title", parent=self)
        self.file_path_Text.delete(1.0, END)
        self.file_path_Text.insert(1.0, filename)

    def selectpath(self):
        # get filename
        filename = filedialog.askdirectory(initialdir="C:\\", title="This is title", parent=self)
        self.path_Text.delete(1.0, END)
        self.path_Text.insert(1.0, filename)

    def divide(self):
        input_file = self.file_path_Text.get(1.0, END)[0:-1]
        output_path = self.path_Text.get(1.0, END)[0:-1]
        try:
            divide_lines = int(self.get_small_file_lins_Text.get(1.0, END)[0:-1])
            divide_number = int(self.get_small_file_number_Text.get(1.0, END)[0:-1])
            if os.path.isfile(input_file) and os.path.isdir(output_path):
                divide_text_by_line(big_file=input_file, small_file_lines=divide_lines, new_file_path=output_path,
                                    times=divide_number)
                messagebox.showwarning('消息', '转换完成！')
            else:
                messagebox.showwarning('警告', '输入文件路径错误或者输出路径错误！')
        except Exception as errors:
            messagebox.showwarning('警告', '请输入数字')
            print(str(errors))


def read_mock_cofig():
    global MOCO_CONFIG_PATH
    number = []
    name = []
    method = []
    url = []
    content = []

    # 获取已有接口配置信息
    config_file = open(MOCO_CONFIG_PATH, "r", encoding="utf-8")
    config_dic = json.load(config_file)
    i = 1
    for config in config_dic:
        number.append(str(i))
        name.append(config['description'])
        method.append(config['request']['method'])
        url.append(config['request']['uri'])
        content.append(json.dumps(config['response']['json']).encode('latin-1').decode('unicode_escape'))
        i = i + 1
    return number, name, method, url, content


def moco_switch(widget):
    if widget["text"] == "启动":
        os.system(MOCO_VBS_PATH)
        widget.config(text="停止")
    else:
        os.system(MOCO_STOP_BAT_PATH)
        widget.config(text="启动")


class mocoPage(ttk.Frame):

    def __init__(self, nb):
        super().__init__(nb)
        # 第5选项卡
        columns = ("序号", "接口名称", "类型", "url", "状态")
        self.treeview = ttk.Treeview(self, show="headings", columns=columns)  # 表格
        self.treeview.column("序号", anchor='center')  # 表示列,不显示
        self.treeview.column("接口名称", anchor='center')
        self.treeview.column("类型", anchor='center')
        self.treeview.column("url", anchor='center')  # 表示列,不显示
        self.treeview.heading("序号", text="序号")  # 显示表头
        self.treeview.heading("接口名称", text="接口名称")
        self.treeview.heading("类型", text="类型")
        self.treeview.heading("url", text="url")  # 显示表头
        self.treeview.grid(row=1, column=1, columnspan=2)
        self.number, self.name, self.method, self.url, self.content = read_mock_cofig()
        for i in range(min(len(self.number), len(self.name))):  # 写入数据
            self.treeview.insert('', i, values=(self.number[i], self.name[i], self.method[i], self.url[i]))
        # 双击左键进入编辑
        self.treeview.bind('<Double-1>', self.edit)
        # 单机右键键进入功能选择菜单
        self.treeview.bind('<Button-3>', self.item_menu)
        self.popup = Menu(self, tearoff=0)
        self.popup.add_command(label="delete", command=self.delete_iterm)
        # self.popup.add_command(label="edit", command=self.edit)
        self.popup.add_separator()
        # 新建接口按键和启动按键
        self.button_frame = Frame(self)
        Button(self.button_frame, text='新建', width=5, command=self.add).grid(row=0, column=1, sticky=E)
        moco_start_stop_button = Button(self.button_frame, text='启动', width=5,
                                        command=lambda: moco_switch(moco_start_stop_button))
        moco_start_stop_button.grid(row=0, column=2, sticky=E)
        self.button_frame.grid(row=0, column=2, sticky=E)
        # 启动MOCO
        string_bat = f"java -Dfile.encoding=UTF-8 -jar {MOCO_PATH} start -p {MOCO_PORT} " \
                     f"-c {MOCO_CONFIG_PATH} > {MOCO_LOG_PATH}"
        with open(MOCO_START_BAT_PATH, "w", encoding="ANSI") as file_:
            file_.writelines(string_bat)
        with open(MOCO_VBS_PATH, "w", encoding="ANSI") as file_:
            file_.writelines(
                "Set ws = CreateObject(\"Wscript.shell\")\nws.run \"cmd /c " + MOCO_START_BAT_PATH + "\",vbhide")
        Label(self, text="默认端口：" + MOCO_PORT).grid(row=0, column=1, sticky=W)
        for col in columns:  # 绑定函数，使表头可排序
            self.treeview.heading(col, text=col,
                                  command=lambda _col=col: self.treeview_sort_column(self.treeview, _col, False))

    def treeview_sort_column(self, tv, col, reverse):  # Treeview、列名、排列方式
        l = [(tv.set(k, col), k) for k in tv.get_children('')]
        l.sort(reverse=reverse)  # 排序方式
        # rearrange items in sorted positions
        for index, (val, k) in enumerate(l):  # 根据排序后索引移动
            tv.move(k, '', index)
        tv.heading(col, command=lambda: self.treeview_sort_column(tv, col, not reverse))  # 重写标题，使之成为再点倒序的标题

    def edit(self, event):  # 双击进入编辑状态
        selection = self.treeview.selection()[0]
        num = self.treeview.index(selection)
        inputDialog = EditAddMocoDialog(
            {'name': self.name[num], 'method': self.method[num], 'url': self.url[num], 'content': self.content[num]})
        self.treeview.wait_window(inputDialog)  # 这一句很重要！！！
        newinfo = inputDialog.userinfo
        if newinfo is None: return
        self.treeview.set(selection, column=1, value=newinfo[0])
        self.treeview.set(selection, column=2, value=newinfo[1])
        self.treeview.set(selection, column=3, value=newinfo[2])
        self.name[num] = newinfo[0]
        self.method[num] = newinfo[1]
        self.url[num] = newinfo[2]
        self.content[num] = newinfo[3]
        number = []
        for j in range(len(self.name)):
            number.append(j + 1)
        self.write_mock_config(
            {'number': number, 'name': self.name, 'url': self.url, "method": self.method, "content": self.content})

    def add(self):
        inputDialog = EditAddMocoDialog({'name': '', 'method': '', 'url': '', 'content': ''})
        self.treeview.wait_window(inputDialog)  # 这一句很重要！！！
        newinfo = inputDialog.userinfo
        # 判断输入的信息是否符合规范
        try:
            output_json_string = newinfo[3]
            output_json = json.loads(output_json_string)
        except:
            messagebox.showwarning('警告', '输入的接口返回值格式错误不是json,添加失败')
            return
        self.name.append(newinfo[0])
        self.method.append(newinfo[1])
        self.url.append(newinfo[2])
        self.content.append(newinfo[3])
        i = len(self.name) - 1
        self.number.append(str(i + 1))
        self.treeview.insert('', i, values=(self.number[i], self.name[i], self.method[i], self.url[i]))
        self.write_mock_config(
            {'number': self.number, 'name': self.name, 'url': self.url, "method": self.method, "content": self.content})

    def write_mock_config(self, config):
        number = config['number']
        name = config['name']
        method = config['method']
        url = config['url']
        content = config['content']
        config_list = []
        for i in number:
            j = int(i) - 1
            config_item = {"request": {
                "uri": "",
                "method": ""
            }, "response": {
                "json": {"code": 200}
            }, 'description': name[j]}
            config_item['request']['method'] = method[j]
            config_item['request']['uri'] = url[j]
            config_item["response"]["json"] = json.loads(content[j])
            config_list.append(config_item)
        global MOCO_CONFIG_PATH
        f = open(MOCO_CONFIG_PATH, "w", encoding="utf-8")
        config_string = json.dumps(config_list).encode('latin-1').decode('unicode_escape')
        f.write(config_string)
        f.close()

    def delete_iterm(self):
        num = self.treeview.index(self.popup.selection)
        self.treeview.delete(self.popup.selection)
        self.name.pop(num)
        self.url.pop(num)
        self.content.pop(num)
        self.method.pop(num)
        self.number.pop()
        self.write_mock_config(
            {'number': self.number, 'name': self.name, 'url': self.url, "method": self.method, "content": self.content})

    def item_menu(self, event):
        # display the popup menu
        try:
            # popup.selection = page5_treeview.set(page5_treeview.identify_row(event.y))
            self.popup.selection = self.treeview.selection()[0]
            self.popup.post(event.x_root, event.y_root)
        finally:
            # make sure to release the grab (Tk 8.0a1 only)
            self.popup.grab_release()


class kafkaProductPage(ttk.Frame):

    def __init__(self, nb):
        super().__init__(nb)
        self.kafka_info_set = set()
        self.kafka_connect_dict = {}
        # 第4选项卡
        page4width = 130
        Label(self, text="kafka连接信息:").grid(row=0, column=0, sticky=E)
        Label(self, text="topic名称:").grid(row=1, column=0, sticky=E)
        Label(self, text="序列化格式:").grid(row=2, column=0, sticky=E)
        Label(self, text="发送数据条数:").grid(row=3, column=0, sticky=E)
        Label(self, text="是否从文件读取数据:").grid(row=4, column=0, sticky=E)
        self.data_file_label = Label(self, text="待发送的文件选择:")
        self.data_file_label.grid(row=5, column=0, sticky=E)
        self.data_label = Label(self, text="待发送数据输入:")
        self.data_label.grid(row=6, column=0, sticky=E)
        Label(self, text="若选择发送多条数据，需要每一行为一条数据").grid(row=3, column=3, sticky=E)
        self.kafka_connect_Text = Text(self, width=page4width, height=1)
        self.kafka_connect_Text.grid(row=0, column=1, columnspan=3, sticky=E)
        self.kafka_topic_name_Text = Text(self, width=page4width, height=1)
        self.kafka_topic_name_Text.grid(row=1, column=1, columnspan=3, sticky=E)
        self.kafka_schema_path_Text = Text(self, width=page4width - 40, height=1, state=DISABLED)
        self.kafka_schema_path_Text.grid(row=2, column=3, columnspan=2, sticky=W)
        self.kafka_data_path_Text = Text(self, width=page4width, height=1, state=DISABLED)
        self.kafka_data_path_Text.grid(row=5, column=1, columnspan=3, sticky=W)
        self.data_frame = Frame(self, width=page4width)
        self.kafka_data_Text = Text(self.data_frame, width=page4width - 2)
        self.kafka_data_Text.pack(expand=1, fill=BOTH, side=LEFT)
        self.scrollbar = Scrollbar(self.data_frame)
        self.scrollbar.pack(side=RIGHT, fill=Y)
        self.kafka_data_Text.config(yscrollcommand=self.scrollbar.set)
        self.scrollbar.config(command=self.kafka_data_Text.yview)
        self.data_frame.grid(row=6, column=1, columnspan=3, sticky=W)
        self.kafka_way = IntVar()
        self.kafka_way.set(0)
        R1 = Radiobutton(self, text="string", variable=self.kafka_way, value=0, command=lambda: self.hide(R1))
        R1.grid(row=2, column=1, sticky=W)
        R2 = Radiobutton(self, text="avro", variable=self.kafka_way, value=1, command=lambda: self.hide(R2))
        R2.grid(row=2, column=2, sticky=W)
        self.send_number = IntVar()
        self.send_number.set(0)
        Radiobutton(self, text="单条数据", variable=self.send_number, value=0).grid(row=3, column=1, sticky=W)
        Radiobutton(self, text="多条数据", variable=self.send_number, value=1).grid(row=3, column=2, sticky=W)
        self.use_file = IntVar()
        self.use_file.set(0)
        R3 = Radiobutton(self, text="是", variable=self.use_file, value=1, command=lambda: self.hide(R3))
        R3.grid(row=4, column=1, sticky=W)
        R4 = Radiobutton(self, text="否", variable=self.use_file, value=0, command=lambda: self.hide(R4))
        R4.grid(row=4, column=2, sticky=W)
        self.kafka_data_path_Text.grid_forget()
        self.data_file_label.grid_forget()
        Button(self, text="测试连接", command=self.kafka_connect).grid(row=0, column=4, sticky=W)
        self.send_frame = Frame(self)
        Button(self.send_frame, text="发送", width=10, command=self.send_data_to_kafka).pack()
        self.send_frame.grid(row=7, column=0, columnspan=5)
        self.select_schema_button = Button(self, text="选择文件", command=self.select_schema_file)
        self.select_schema_button.grid(row=2, column=4, sticky=W)
        self.select_data_file_button = Button(self, text="选择文件", command=self.select_data_file)
        self.select_data_file_button.grid(row=4, column=4, sticky=W)
        self.kafka_schema_path_Text.grid_forget()
        self.select_schema_button.grid_forget()
        self.select_data_file_button.grid_forget()

    def send_data_to_kafka(self):
        topic_name = self.kafka_topic_name_Text.get(1.0, END)[:-1]
        bootstrap_servers = self.kafka_connect_Text.get(1.0, END)[:-1]
        if bootstrap_servers not in self.kafka_info_set:
            messagebox.showinfo('警告', '请先进行测试连接！')
            return
        kafka_connection_info = self.kafka_connect_dict[bootstrap_servers]
        if topic_name not in kafka_connection_info.topic_list:
            messagebox.showinfo('警告', '选择的topic名称不存在')
            return
        if self.use_file.get() == 0:
            # 不使用文件发送数据
            send_data = self.kafka_data_Text.get(1.0, END)[:-1]
            if self.send_number == 0:
                # 发送单条数据
                send_data.replace("\n", "")
        else:
            send_data = self.kafka_data_path_Text.get(1.0, END)[:-1]
        if self.kafka_way.get() == 1:
            # 序列化方式为avro
            schema_path = self.kafka_schema_path_Text.get(1.0, END)[:-1]
            if self.use_file.get() == 0:
                kafka_connection_info.send_avro_data(topic_name, send_data, schema_path, data_method='data')
            else:
                kafka_connection_info.send_avro_data(topic_name, send_data, schema_path, data_method='file')
        else:
            # 序列化方式为string
            if self.use_file.get() == 0:
                # 不使用文件发送数据
                kafka_connection_info.send_string_data(topic_name, send_data, data_method='data')
            else:
                kafka_connection_info.send_string_data(topic_name, send_data, data_method='file')

    def kafka_connect(self):
        bootstrap_servers = self.kafka_connect_Text.get(1.0, END)[:-1]
        if bootstrap_servers == "":
            messagebox.showinfo('警告', '请输入kafka的连接信息')
            return
        try:
            test_result, connect_info = test_kafka2(bootstrap_servers)
            if test_result:
                self.kafka_info_set.add(bootstrap_servers)
                self.kafka_connect_dict[bootstrap_servers] = connect_info
                messagebox.showinfo('提示', 'kafka连接信息测试连接通过')
            else:
                messagebox.showinfo('警告', 'kafka连接信息测试连接失败！')
        except func_timeout.exceptions.FunctionTimedOut:
            messagebox.showinfo('警告', 'kafka连接信息测试连接超时！')

    def select_schema_file(self):
        filename = filedialog.askopenfilename(initialdir="C:\\", title="请选择schema文件", parent=self)
        self.kafka_schema_path_Text.config(state=NORMAL)
        self.kafka_schema_path_Text.delete(1.0, END)
        self.kafka_schema_path_Text.insert(1.0, filename)
        self.kafka_schema_path_Text.config(state=DISABLED)

    def select_data_file(self):
        filename = filedialog.askopenfilename(initialdir="C:\\", title="请选择数据文件", parent=self)
        self.kafka_data_path_Text.config(state=NORMAL)
        self.kafka_data_path_Text.delete(1.0, END)
        self.kafka_data_path_Text.insert(1.0, filename)
        self.kafka_data_path_Text.config(state=DISABLED)

    def hide(self, widget):
        if widget["text"] == "string":
            self.kafka_schema_path_Text.grid_forget()
            self.select_schema_button.grid_forget()
        elif widget["text"] == "avro":
            self.kafka_schema_path_Text.grid(row=2, column=3, columnspan=2, sticky=E)
            self.select_schema_button.grid(row=2, column=4, sticky=W)
        elif widget["text"] == "是":
            self.data_frame.grid_forget()
            self.data_label.grid_forget()
            self.kafka_data_path_Text.grid(row=5, column=1, columnspan=3, sticky=E)
            self.data_file_label.grid(row=5, column=0, sticky=E)
            self.select_data_file_button.grid(row=5, column=4, sticky=W)
        else:
            self.data_label.grid(row=6, column=0, sticky=E)
            self.data_frame.grid(row=6, column=1, columnspan=3, sticky=E)
            self.kafka_data_path_Text.grid_forget()
            self.data_file_label.grid_forget()
            self.select_data_file_button.grid_forget()


class MainDialog(Tk):
    def __init__(self, conf):
        super().__init__()
        self.title("小工具v1.1")

        mb = Menubutton(self, text="设置", relief=RAISED)
        filemenu = Menu(mb, tearoff=False)
        filemenu.add_command(label="设置页面", command=self.top_frame_settings)
        filemenu.add_separator()
        filemenu.add_command(label="退出", command=self.quit)
        mb.config(menu=filemenu)
        mb.grid(row=0, column=1, sticky=E + N)
        self.page_show_dic = conf["page_dic"]

        self.nb = ttk.Notebook(self)
        self.page1 = dataTransPage(self.nb)
        self.page2 = fileTransPage(self.nb)
        self.page3 = fileDividePage(self.nb)
        self.page4 = kafkaProductPage(self.nb)
        self.page5 = mocoPage(self.nb)
        self.nb.grid(row=0, column=0)

        self.PageDic = {
            "dataTransPage": self.page1,
            "fileTransPage": self.page2,
            "fileDividePage": self.page3,
            "kafkaProductPage": self.page4,
            "mocoPage": self.page5
        }
        self.PageName = {
            "dataTransPage": '输入转换',
            "fileTransPage": '文档转换',
            "fileDividePage": '大文件分割',
            "kafkaProductPage": 'Kafka发送数据工具',
            "mocoPage": '接口模拟'
        }
        self.all_page_alias_list = list(self.PageName.values())
        self.all_page_name_list = list(self.PageName.keys())
        for page in self.all_page_name_list:
            if self.page_show_dic[page] == 1:
                self.nb.add(self.PageDic[page], text=self.PageName[page])

        # 退出窗口时进行的动作
        self.protocol("WM_DELETE_WINDOW", self.on_closing)

    def top_frame_settings(self):
        settingWindow = settings(self.page_show_dic)
        self.wait_window(settingWindow)
        page_show_dic = settingWindow.page_display_dic
        for pageName in self.all_page_name_list:
            if page_show_dic[pageName] == 1:
                self.nb.add(self.PageDic[pageName], text=self.PageName[pageName])
            else:
                self.nb.forget(self.PageDic[pageName])

    def on_closing(self):
        os.system(MOCO_STOP_BAT_PATH)
        little_tools.destroy()


if __name__ == "__main__":
    exec_path, exec_filename = os.path.split(os.path.abspath(__file__))
    MOCO = os.path.join(exec_path, "conf") + "\\"
    MOCO_CONFIG_PATH = MOCO + 'config.json'
    MOCO_PATH = MOCO + 'moco-runner-1.1.0-standalone.jar'
    MOCO_START_BAT_PATH = MOCO + 'start.bat'
    MOCO_STOP_BAT_PATH = MOCO + 'stop.bat'
    MOCO_VBS_PATH = MOCO + 'start.vbs'
    MOCO_LOG_PATH = MOCO + 'moco.log'
    MOCO_PORT = "10012"
    little_tools_conf_path = MOCO + "littleTools.ini"
    config = configparser.ConfigParser()
    config.read(little_tools_conf_path)
    little_tools_conf = {}
    little_tools_conf["page_dic"] = json.loads(config["page_settings"]["page_dic"])

    little_tools = MainDialog(little_tools_conf)
    little_tools.mainloop()
